import React, {
  createContext,
  useContext,
  useRef,
  useState,
  useEffect,
} from "react";

interface ThemeContextProps {
  theme: "light" | "dark";
  masking: boolean;
  handleThemeSwitch: (center?: { x: number; y: number }) => void;
  maskRef: React.RefObject<HTMLDivElement>;
  maskColor: string;
  maskCenter: { x: number; y: number };
}

const ThemeContext = createContext<ThemeContextProps | undefined>(undefined);

export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({
  children,
}) => {
  // 初始值根据系统主题
  const getSystemTheme = () =>
    window.matchMedia("(prefers-color-scheme: dark)").matches
      ? "dark"
      : "light";
  const [theme, setTheme] = useState<"light" | "dark">(getSystemTheme());
  const [masking, setMasking] = useState(false);
  const [nextTheme, setNextTheme] = useState<"light" | "dark">(
    getSystemTheme()
  );
  const [maskCenter, setMaskCenter] = useState({
    x: window.innerWidth - 40,
    y: 40,
  });
  const maskRef = useRef<HTMLDivElement>(null);

  // 监听系统主题变化自动切换
  useEffect(() => {
    const mq = window.matchMedia("(prefers-color-scheme: dark)");
    const handler = (e: MediaQueryListEvent) =>
      setTheme(e.matches ? "dark" : "light");
    mq.addEventListener("change", handler);
    return () => mq.removeEventListener("change", handler);
  }, []);

  useEffect(() => {
    const html = document.documentElement;
    if (theme === "dark") {
      html.classList.add("dark");
    } else {
      html.classList.remove("dark");
    }
    return () => html.classList.remove("dark");
  }, [theme]);

  // 切换主题时，动画用目标色，动画结束后再切换主题
  const handleThemeSwitch = (center?: { x: number; y: number }) => {
    setNextTheme(theme === "dark" ? "light" : "dark"); // 先设置目标主题
    setMasking(true); // 再开始动画
    if (center) setMaskCenter(center);
    else setMaskCenter({ x: window.innerWidth - 40, y: 40 });
  };

  useEffect(() => {
    if (!masking) return;
    const timer = setTimeout(() => {
      setTheme(nextTheme); // 动画结束后再切换主题
      setMasking(false);
    }, 700);
    return () => clearTimeout(timer);
  }, [masking, nextTheme]);

  // 动画时用目标主题色，非动画时用当前主题色
  const maskColor = masking
    ? nextTheme === "dark"
      ? "#181c27"
      : "#fff"
    : theme === "dark"
    ? "#181c27"
    : "#fff";

  return (
    <ThemeContext.Provider
      value={{
        theme,
        masking,
        handleThemeSwitch,
        maskRef,
        maskColor,
        maskCenter,
      }}
    >
      {children}
    </ThemeContext.Provider>
  );
};

export const useThemeContext = () => {
  const ctx = useContext(ThemeContext);
  if (!ctx)
    throw new Error("useThemeContext must be used within ThemeProvider");
  return ctx;
};
